package logger

import (
	"fmt"
	"os"
	"path/filepath"
	"time"
	"wms/config"
	"wms/pkg/global"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

var Logger *zap.Logger

// InitLogger 初始化日志
func InitLogger(config *config.LogConfig) (*zap.Logger, error) {
	// 创建日志目录
	logDir := "logs"
	if err := os.MkdirAll(logDir, 0755); err != nil {
		return nil, fmt.Errorf("创建日志目录失败: %w", err)
	}

	// 构建日志文件路径
	logFilePath := filepath.Join(logDir, "wms.log")

	// 创建日志文件
	logFile, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		return nil, fmt.Errorf("创建日志文件失败: %w", err)
	}

	// 设置日志级别
	var level zapcore.Level
	switch config.Level {
	case "debug":
		level = zapcore.DebugLevel
	case "info":
		level = zapcore.InfoLevel
	case "warn":
		level = zapcore.WarnLevel
	case "error":
		level = zapcore.ErrorLevel
	default:
		level = zapcore.InfoLevel
	}

	// 配置编码器 - 简化输出格式
	encoderConfig := zapcore.EncoderConfig{
		TimeKey:        "time",
		LevelKey:       "level",
		NameKey:        "logger",
		CallerKey:      "caller",
		MessageKey:     "msg",
		StacktraceKey:  "stacktrace",
		LineEnding:     zapcore.DefaultLineEnding,
		EncodeLevel:    zapcore.CapitalLevelEncoder,
		EncodeTime:     simpleTimeEncoder,
		EncodeDuration: zapcore.SecondsDurationEncoder,
		EncodeCaller:   zapcore.ShortCallerEncoder,
	}

	// 设置核心
	core := zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderConfig),
		zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(logFile)),
		level,
	)

	// 创建logger
	logger := zap.New(core, zap.AddCaller())
	Logger = logger
	global.Logger = logger

	// 记录系统启动日志
	LogOperation("系统启动", 0, "服务器启动成功")

	return logger, nil
}

// simpleTimeEncoder 简化的时间编码器
func simpleTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
	enc.AppendString(t.Format("2006-01-02 15:04:05"))
}

// GetLogger 获取全局Logger
func GetLogger() *zap.Logger {
	if global.Logger == nil {
		// 创建默认Logger
		encoder := zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
			TimeKey:        "time",
			LevelKey:       "level",
			NameKey:        "logger",
			CallerKey:      "caller",
			MessageKey:     "msg",
			StacktraceKey:  "stacktrace",
			LineEnding:     zapcore.DefaultLineEnding,
			EncodeLevel:    zapcore.CapitalLevelEncoder,
			EncodeTime:     simpleTimeEncoder,
			EncodeDuration: zapcore.SecondsDurationEncoder,
			EncodeCaller:   zapcore.ShortCallerEncoder,
		})
		core := zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zap.InfoLevel)
		global.Logger = zap.New(core, zap.AddCaller())
	}
	return global.Logger
}

// Debug 调试日志 - 仅在开发环境使用
func Debug(msg string, fields ...zap.Field) {
	GetLogger().Debug(msg, fields...)
}

// Info 信息日志 - 非业务操作日志，仅记录技术信息
func Info(msg string, fields ...zap.Field) {
	// 判断是否是开发模式，如果不是则不记录普通的INFO日志
	if os.Getenv("WMS_ENV") == "development" {
		GetLogger().Info(msg, fields...)
	}
}

// Warn 警告日志
func Warn(msg string, fields ...zap.Field) {
	GetLogger().Warn(msg, fields...)
}

// Error 错误日志
func Error(msg string, fields ...zap.Field) {
	GetLogger().Error(msg, fields...)
}

// Fatal 致命错误日志
func Fatal(msg string, fields ...zap.Field) {
	GetLogger().Fatal(msg, fields...)
}

// LogOperation 记录操作日志，方便前端展示
func LogOperation(operation string, userID uint, details string) {
	if global.Logger != nil {
		global.Logger.Info(operation,
			zap.Uint("user_id", userID),
			zap.String("details", details),
			zap.String("type", "operation"))
	}
}

// LogLogin 记录登录日志
func LogLogin(username string, userID uint, success bool, ip string) {
	status := "成功"
	if !success {
		status = "失败"
	}

	details := fmt.Sprintf("用户 %s 登录%s，IP: %s", username, status, ip)
	if global.Logger != nil {
		global.Logger.Info("用户登录",
			zap.String("username", username),
			zap.Uint("user_id", userID),
			zap.Bool("success", success),
			zap.String("ip", ip),
			zap.String("details", details),
			zap.String("type", "login"))
	}
}

// LogLogout 记录登出日志
func LogLogout(username string, userID uint) {
	details := fmt.Sprintf("用户 %s 退出登录", username)
	if global.Logger != nil {
		global.Logger.Info("用户登出",
			zap.String("username", username),
			zap.Uint("user_id", userID),
			zap.String("details", details),
			zap.String("type", "logout"))
	}
}

// LogInventoryOperation 记录库存操作日志
func LogInventoryOperation(operation string, userID uint, cargoName string, quantity float64, locationName string, orderCode string) {
	details := fmt.Sprintf("%s: %s %.2f %s 单号:%s", operation, cargoName, quantity, locationName, orderCode)
	if global.Logger != nil {
		global.Logger.Info(operation,
			zap.Uint("user_id", userID),
			zap.String("cargo", cargoName),
			zap.Float64("quantity", quantity),
			zap.String("location", locationName),
			zap.String("order_code", orderCode),
			zap.String("details", details),
			zap.String("type", "inventory"))
	}
}

// LogDataOperation 记录数据操作日志
func LogDataOperation(operation string, userID uint, dataType string, dataID uint, dataName string, action string) {
	details := fmt.Sprintf("%s %s: %s (ID:%d)", action, dataType, dataName, dataID)
	if global.Logger != nil {
		global.Logger.Info(operation,
			zap.Uint("user_id", userID),
			zap.String("data_type", dataType),
			zap.Uint("data_id", dataID),
			zap.String("data_name", dataName),
			zap.String("action", action),
			zap.String("details", details),
			zap.String("type", "data"))
	}
}
